package com.iflytek.jzcpx.procuracy.cont.service.impl;

import com.iflytek.jzcpx.procuracy.cont.common.config.EDSConfig;
import com.iflytek.jzcpx.procuracy.cont.common.util.OcrUtilNew;
import com.iflytek.jzcpx.procuracy.cont.enums.PromeMetricEnum;
import com.iflytek.jzcpx.procuracy.cont.model.JsonResult;
import com.iflytek.jzcpx.procuracy.cont.model.PicDataNew;
import com.iflytek.jzcpx.procuracy.cont.model.SuccessJsonResult;
import com.iflytek.jzcpx.procuracy.cont.service.PromethusService;
import com.iflytek.ocr.client.OcrClient;
import com.iflytek.ocr.data.RestResponse;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 图像识别接口
 *
 * @author lli
 * @version 1.0
 */
@Service
public class IflytekOcrService {

	/**
	 * 
	 */
	private static final Logger logger = LoggerFactory.getLogger(IflytekOcrService.class);

	/**
	 * 
	 */
	@Autowired
	private EDSConfig edsConfig;

	/**
	 * 
	 */
	@Autowired
	private OcrClient ocrClient;

	/**
	 * 
	 */
	@Autowired
	private PromethusService promethusService;

	/**
	 * @param picData
	 * @return
	 * @throws Exception
	 * @description 文件扫描接口
	 * @author lli
	 * @create 2017年8月17日上午11:10:53
	 * @version 1.0
	 */

	public String ocr(PicDataNew picData) {
		long start = System.currentTimeMillis();
		OcrUtilNew.addNum();
		logger.info("识别开始，当前识别数{},uid:{}", OcrUtilNew.getNum(), picData.getImageId());

		/** ocr识别 **/
		String ocrJson = null;
		if ("new".equals(edsConfig.getOcrMethod())) {
			/** http方式调用 **/
			ocrJson = getOcr(picData.getData(), picData.getImageId());
		} else {
			/** 动态库方式调用 **/
			ocrJson = OcrUtilNew.queryOcr(picData.getData());
		}
		OcrUtilNew.reduceNum();
		logger.info("识别结束,耗时{}ms,当前识别数{},uid:{}", (System.currentTimeMillis() - start), OcrUtilNew.getNum(),
				picData.getImageId());
		return ocrJson;

	}

	/***
	 * 通过新的SDK方式调ocr3.0引擎(v2，http方式) 图像识别转换为文字
	 */
	public String getOcrByFile(File file, String imageId) {
		Map<String, Object> params = new HashMap<>();
		params.put("resultLevel", 3);
		String resultStr = "";
		RestResponse<String> result;
		/** 开始图片识别 **/
		try {
			result = ocrClient.recognize(imageId, file, params);
			if (result != null) {
				if (result.state.isSuccess()) {
					resultStr = result.body;
					logger.info("ocr识别成功");
				} else {
					String errMessage = result.state.exception.getMessage();
					promethusService.counterType(null, PromeMetricEnum.OCR_FAIL_COUNT.getName(), 1,
							StrUtil.format("errorCode,{}", errMessage.replace(",", " ")));
				}
			}
		} catch (Exception e) {
			resultStr = "";
			logger.error("ocr识别失败,原因:" + e.getMessage());
		}
		return resultStr;
	}

	/***
	 * 通过新的SDK方式调ocr引擎(v2，http方式) 图像识别转换为文字
	 */
	private String getOcr(byte[] data, String imageId) {
		Map<String, Object> params = new HashMap<>();
		String resultStr = "";
		RestResponse<String> result;
		/** 开始图片识别 **/
		try {
			result = ocrClient.recognize(imageId, data, params);
			if (result != null) {
				if (result.state.isSuccess()) {
					resultStr = result.body;
					logger.info("ocr识别成功");
				} else {
					String errMessage = result.state.exception.getMessage();
					promethusService.counterType(null, PromeMetricEnum.OCR_FAIL_COUNT.getName(), 1,
							StrUtil.format("errorCode,{}", errMessage.replace(",", " ")));
				}
			}
		} catch (Exception e) {
			resultStr = "";
			logger.error("ocr识别失败,原因:" + e.getMessage());
		}

		return resultStr;
	}

	public String getSinglineOcr(String imageId, File file, Map<String, Object> params) {

		String resultStr = "";
		/** 开始图片识别 **/
		try {
			RestResponse<String> result = ocrClient.recognize(imageId, file, params);
			if (result != null) {
				if (result.state.isSuccess()) {
					resultStr = result.body;
					logger.info("ocr单行识别成功");

				}
			}
		} catch (Exception e) {
			resultStr = "";
			logger.error("ocr单行识别失败,原因,{}", e);
		}

		return resultStr;
	}

	/**
	 * @param
	 * @return
	 * @throws Exception
	 * @description 文件扫描接口
	 * @author lli
	 * @create 2017年8月17日上午11:10:53
	 * @version 1.0
	 */

	public List<JsonResult> ocrFile(MultipartFile file) throws IOException {
		List<JsonResult> resList = new ArrayList<JsonResult>();
		byte[] buffer = GetImageStr(file.getInputStream());
		long start = System.currentTimeMillis();
		OcrUtilNew.addNum();
		logger.info("识别开始，当前识别数{},uid:{}", OcrUtilNew.getNum(), UUID.randomUUID());

		/** ocr识别 **/
		String ocrJson = null;
		if ("new".equals(edsConfig.getOcrMethod())) {
			/** http方式调用 **/
			ocrJson = getOcr(buffer, UUID.randomUUID().toString());
		} else {
			/** 动态库方式调用 **/
			ocrJson = OcrUtilNew.queryOcr(buffer);
		}

		SuccessJsonResult<String> result = new SuccessJsonResult<>();
		result.setData(ocrJson);

		resList.add(result);
		OcrUtilNew.reduceNum();
		logger.info("识别结束,耗时{}ms,当前识别数{},uid:{}", (System.currentTimeMillis() - start), OcrUtilNew.getNum(),
				UUID.randomUUID().toString());
		return resList;

	}

	private static byte[] GetImageStr(InputStream in) {// 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
		byte[] data = null;
		// 读取图片字节数组
		try {
			data = new byte[in.available()];
			in.read(data);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 对字节数组Base64编码
		return data;
	}
}
